
const DissolveShader = {
  shaderID: 'DissolveShader',

  uniforms: {
    'iTime': { value: 1.0 },
    'modelHeight': { value: 1.0 }, // 模型高度，约定模型的原点位于底部投影的中心
    'modelWidth': { value: 1.0 },
    'modelDepth': { value: 1.0 },
  },

  vertexShader: /* glsl */`
  varying float height;
  varying float width;
  varying float deep;
  uniform float modelHeight;
  uniform float modelWidth;
  uniform float modelDepth;

  void main() {
    height = position.y + modelHeight * 0.5;
    width = position.x + modelWidth * 0.5;
    deep = position.z + modelDepth * 0.5;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
  }`,

  fragmentShader: /* glsl */`
  precision highp float;
  precision highp sampler3D;
					
  #define epsilon .0001
  
  uniform sampler3D map;
	uniform float iTime;
  uniform float modelHeight;
  uniform float modelWidth;
  uniform float modelDepth;
  varying float height;
  varying float width;
  varying float deep;
  
  float sample1( vec3 p ) {
    return texture( map, p ).r;
  }
  
  vec3 normal( vec3 coord ) {
    if ( coord.x < epsilon ) return vec3( 1.0, 0.0, 0.0 );
    if ( coord.y < epsilon ) return vec3( 0.0, 1.0, 0.0 );
    if ( coord.z < epsilon ) return vec3( 0.0, 0.0, 1.0 );
    if ( coord.x > 1.0 - epsilon ) return vec3( - 1.0, 0.0, 0.0 );
    if ( coord.y > 1.0 - epsilon ) return vec3( 0.0, - 1.0, 0.0 );
    if ( coord.z > 1.0 - epsilon ) return vec3( 0.0, 0.0, - 1.0 );

    float step = 0.01;
    float x = sample1( coord + vec3( - step, 0.0, 0.0 ) ) - sample1( coord + vec3( step, 0.0, 0.0 ) );
    float y = sample1( coord + vec3( 0.0, - step, 0.0 ) ) - sample1( coord + vec3( 0.0, step, 0.0 ) );
    float z = sample1( coord + vec3( 0.0, 0.0, - step ) ) - sample1( coord + vec3( 0.0, 0.0, step ) );

    return normalize( vec3( x, y, z ) );
  }
					
  void main() {
    vec3 uv = vec3(height / modelHeight, width / modelWidth, deep / modelDepth);
    float minVal = min(min(modelHeight, modelWidth), modelDepth);
    uv *= vec3(modelHeight, modelWidth, modelDepth) / minVal * 2.0;
    uv = fract(uv);
    float d = sample1( uv );
    float threshold = sin(iTime * 2.0) * 0.5 + 0.5;
    if (d > threshold) {
      discard;
    }
    
    gl_FragColor = vec4(vec3(d), 1.0);
  }
  
`
}

export default DissolveShader;
